/*
 * @Author: liuzelin
 * @Date: 2024-04-06 10:40:26
 * @LastEditors: liuzelin
 * @LastEditTime: 2024-04-06 12:21:49
 * @Description: copy from webrtc
 */
#pragma once

#include <string>
#include <vector>
#include <optional>

namespace PandaUtils
{
    class Histogram
    {
    public:
        // Creates histogram with capacity |num_buckets| and |forget_factor| in Q15.
        Histogram(size_t num_buckets,
                  int forget_factor,
                  std::optional<double> start_forget_weight = std::nullopt);

        virtual ~Histogram();

        // Resets the histogram to the default start distribution.
        virtual void Reset();

        // Add entry in bucket |index|.
        virtual void Add(int index);

        // Calculates the quantile at |probability| (in Q30) of the histogram
        // distribution.
        virtual int Quantile(int probability);

        // Apply compression or stretching to the histogram.
        virtual void Scale(int old_bucket_width, int new_bucket_width);

        // Returns the number of buckets in the histogram.
        virtual int NumBuckets() const;

        // Returns the probability for each bucket in Q30.
        std::vector<int> buckets() const { return buckets_; }

        // Made public for testing.
        static std::vector<int> ScaleBuckets(const std::vector<int> &buckets,
                                             int old_bucket_width,
                                             int new_bucket_width);

        // Accessors only intended for testing purposes.
        int base_forget_factor_for_testing() const { return base_forget_factor_; }
        int forget_factor_for_testing() const { return forget_factor_; }
        std::optional<double> start_forget_weight_for_testing() const
        {
            return start_forget_weight_;
        }

    private:
        std::vector<int> buckets_;
        int forget_factor_; // Q15
        const int base_forget_factor_;
        int add_count_;
        const std::optional<double> start_forget_weight_;
    };

}